

let {vec3} = require('gl-matrix');

const tmpv1 = vec3.create();
const tmpv2 = vec3.create();
const tmpv3 = vec3.create();

const v0 = vec3.create();
const v1 = vec3.create();
const v2 = vec3.create();


/**
 *
 * @param  data:{
    positions: number[],
    normals: number[],
    texCoords: number[],
    indices: number[]
}
 */
function computeNormals(data) {

    let indices = data.indices;
    let positions = data.positions;
    data.normals.length = data.positions.length;

    let v01 = tmpv1;
    let v12 = tmpv2;
    let nor = tmpv3;

    // 先计算所有的面法线
    let faceLen = indices.length / 3;
    let f = {};
    let v = {};  // 顶点索引i属于 哪几个面
    for (let i = 0; i < faceLen; ++i) {
        let i0 = indices[3 * i];
        let i1 = indices[3 * i + 1];
        let i2 = indices[3 * i + 2];

        if (!v[i0]){
            v[i0] = [];
        }
        v[i0].push(i);

        if (!v[i1]){
            v[i1] = [];
        }
        v[i1].push(i);

        if (!v[i2]){
            v[i2] = [];
        }
        v[i2].push(i);


        vec3.set(v0, positions[3 * i0], positions[3 * i0 + 1], positions[3 * i0 + 2]);
        vec3.set(v1, positions[3 * i1], positions[3 * i1 + 1], positions[3 * i1 + 2]);
        vec3.set(v2, positions[3 * i2], positions[3 * i2 + 1], positions[3 * i2 + 2]);

        vec3.sub(v01,v1,v0);
        vec3.sub(v12,v2,v1);
        vec3.cross(nor,v01,v12);
        vec3.normalize(nor,nor);
        f[i] = vec3.fromValues(nor[0],nor[1],nor[2]);
    }

    // 计算顶点的平均法线
    let posLen = positions.length / 3;
    let sum = tmpv1;
    for (let i = 0; i < posLen; ++i){
        vec3.set(sum,0,0,0);
        v[i].forEach(faceIdx=>{
            vec3.add(sum,sum,f[faceIdx]);
        });
        vec3.normalize(sum,sum);
        data.normals[3 * i] = sum[0];
        data.normals[3 * i + 1] = sum[1];
        data.normals[3 * i + 2] = sum[2];
    }
}

module.exports = {
    computeNormals
};
